package com.net.xpay.backend.scheduler;

import com.net.xpay.common.domain.User;
import com.net.xpay.common.manager.UserManager;
import com.net.xpay.core.constant.CoreConstant;
import com.net.xpay.core.domain.auto.AutoPayTransBatch;
import com.net.xpay.core.enums.AutoPayTransBatchStatus;
import com.net.xpay.core.manager.auto.AutoPayTransBatchManager;
import com.net.xpay.core.model.AutoPayTransBatchSearchModel;
import com.net.xpay.core.service.auto.AutoPayService;
import com.net.shard.ShardDataSource;
import com.net.shard.ShardDataSourceConfigurer;
import com.net.shard.ShardUtil;
import com.net.shard.domain.ShardConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 自动付定时任务
 */
@Slf4j
@Component
public class AutoPayScheduler {

    @Autowired
    @Qualifier("shardDataSource")
    private DataSource shardDataSource;

    @Autowired
    private AutoPayTransBatchManager autoPayTransBatchManager;

    @Autowired
    private AutoPayService autoPayService;

    @Autowired
    private UserManager userManager;

    /**
     * 定时关闭超时未支付的自动付批次
     */
    @Scheduled(cron = "*/5 * * * * *")
    public void closeAutoPayTransBatch() {
        ShardDataSourceConfigurer shardDataSourceConfigurer = ((ShardDataSource) shardDataSource).getShardDataSourceConfigurer();
        Map<Long, ShardConfig> shardConfigMap = shardDataSourceConfigurer.getShardConfigMap();
        for (Long shardId : shardConfigMap.keySet()) {
            try {
                ShardUtil.setShardContext(shardId);
                doCloseAutoPayTransBatch();
            } catch (Exception e) {
                log.warn("closeAutoPayTransBatch error", e);
            } finally {
                ShardUtil.cleanShardContext();
            }
        }
    }

    private void doCloseAutoPayTransBatch() {
        AutoPayTransBatchSearchModel searchModel = new AutoPayTransBatchSearchModel();
        searchModel.setStatus(AutoPayTransBatchStatus.WAIT_PAY);
        searchModel.setMaxDealTime(LocalDateTime.now().minusMinutes(CoreConstant.AUTO_PAY_EXPIRED_TIME));
        List<AutoPayTransBatch> batches = autoPayTransBatchManager.list(searchModel);

        if (CollectionUtils.isEmpty(batches)) {
            return;
        }

        for (AutoPayTransBatch batch : batches) {
            try {
                User user = userManager.getById(batch.getUserId());
                autoPayService.closeAutoPayTransBatch(user, batch.getId());
            } catch (Exception e) {
                log.warn("doCloseAutoPayTransBatch failed|id={}|userId={}", batch.getId(), batch.getUserId(), e);
            }

        }
    }
}
